package com.example.lib_widget.redpacket;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.lib_widget.R;

/**
 * @author yaotianxue
 * @description
 * @date 2024/10/26
 */
public class RedPacketView extends View {
    public static String TAG="RedPacketView";
    private Paint bgPaint;
    private Paint fgPaint;
    private Paint bitmapPaint;
    int storkeWidth=10; //圆环粗细 dp转px

    /**
     * 默认宽高
     */
    private int defaultWidth=150;
    private int defaultHeight=150;

    /**
     * 图片范围
     */
    private Bitmap bitmap;
    private Rect rect;
    private Rect dst;

    /**
     * 弧形范围
     */
    private RectF rectF=null;


    /**
     * 扫描弧度
     */
    private int angle=0;

    /**
     * view中心点
     */
    int centerX=0;
    int centerY=0;
    //接口回调
    private Callback callback=null;
    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public interface Callback{
        void start();
        void pause(int angle);
        void resume();
        void completed();
    }

    public RedPacketView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initPaint();
    }

    public RedPacketView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    public RedPacketView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public RedPacketView(Context context) {
        super(context);
        initPaint();
    }
    private ValueAnimator valueAnimator;

    /**
     * 开始动画
     */
    public void startAnimator(){
        valueAnimator = ValueAnimator.ofFloat(0,1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                float value= (float) animation.getAnimatedValue();//小数点
                angle = (int) (value*360);
                //刷新onDraw
                invalidate();
            }
        });
        valueAnimator.addPauseListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationPause(Animator animation) {
                super.onAnimationPause(animation);
                if(null != callback){
                    callback.pause(angle);
                }
            }

            @Override
            public void onAnimationResume(Animator animation) {
                super.onAnimationResume(animation);
                if(null != callback){
                    callback.resume();
                }
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {
                super.onAnimationCancel(animation);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if(null != callback){
                    angle = 0;
                    invalidate();
                    callback.completed();
                }

            }
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                if(null != callback){
                    callback.start();
                }
            }
        });
        valueAnimator.setDuration(10000);
        valueAnimator.start();

    }
    public void pause() {
        if (valueAnimator != null) {
            valueAnimator.pause();
        }
    }
    public void resume(){
        if(valueAnimator != null){
            valueAnimator.resume();
        }
    }
    public void stop(){
        if(valueAnimator != null){
            valueAnimator.cancel();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(null != bitmap){
            bitmap.recycle();
        }
    }

    /**
     * 尺寸大小改变初始化bitmap，绘制范围
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "onSizeChanged新 w:"+w+"h:"+h);
        Log.d(TAG, "onSizeChanged旧 w:"+oldw+"h:"+oldh);
        bitmap=getBitmap(R.drawable.redpacket,getMeasuredWidth()/2,getMeasuredHeight()/2);

        //获得当前view的测量之后的中心点
        centerX=getMeasuredWidth()/2;
        centerY=getMeasuredHeight()/2;
        //图片本身大小范围rect、位置范围dst
        rect = new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
        dst = new Rect(centerX-bitmap.getWidth()/2,centerY-bitmap.getHeight()/2,centerX+bitmap.getWidth()/2,centerY+getHeight()/2);
        //圆环
        int padding=storkeWidth+2;
        rectF = new RectF(padding,padding,getMeasuredWidth()-padding,getMeasuredHeight()-padding);
    }

    /**
     * 二次采样
     * @param id
     * @param w
     * @param h
     * @return
     */
    private Bitmap getBitmap(int id,int w,int h) {
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeResource(getResources(),id,options);
        int oldWidth=options.outWidth;
        int oldHeight=options.outHeight;
//        int min = Math.min(oldWidth, oldHeight);

        int sampleSize = 1;
        while (oldHeight / sampleSize > h || oldWidth / sampleSize > w) {
            sampleSize *= 2;
        }
        options.inJustDecodeBounds=false;
        options.inSampleSize=sampleSize;
        options.inPreferredConfig= Bitmap.Config.RGB_565;

        Bitmap result= BitmapFactory.decodeResource(getResources(),R.drawable.redpacket,options);
        return result;
    }

    /**
     *测量：wrap和match效果一样
     * MeasureSpec 32位 = 2位测试模式 +30位测量大小
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d(TAG, "onMeasure: ");
        //宽度
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //高度
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if(widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(defaultWidth,defaultHeight);
        }else if(widthMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(defaultWidth,heightSize);
        }else if(heightMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSize,defaultHeight);
        }
    }

    /**
     * 绘制 bitmap 背景圆环  前景圆环
     * 不要创建对象，内存抖动
     */
    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw: angle"+angle);
        canvas.drawBitmap(bitmap,rect,dst,bitmapPaint);
        canvas.drawArc(rectF,0,360,false,bgPaint);
        canvas.drawArc(rectF,270,angle,false,fgPaint);
    }

    /**
     * 初始化画笔
     */
    public void initPaint(){
        //灰色背景圆环
        bgPaint=new Paint();
        bgPaint.setStyle(Paint.Style.STROKE);//空心
        bgPaint.setColor(Color.rgb(221,221,221));//灰色
        bgPaint.setStrokeWidth(storkeWidth);//粗细
        //红色前景圆环
        fgPaint=new Paint();
        fgPaint.setStyle(Paint.Style.STROKE);
        fgPaint.setColor(Color.rgb(255,0,51));//红色
        fgPaint.setStrokeWidth(storkeWidth);
        //图片画笔
        bitmapPaint=new Paint();
        bitmapPaint.setAntiAlias(true);
        bitmapPaint.setDither(true);
    }
}
